/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package Klassen;

import java.util.ArrayList;

/**
 *
 * @author Serenity
 */
public class Field {
    private int value;
    private int position_x;
    private int position_y;
    private ArrayList<Integer> possible_values;
    private Row yRow;
    private Row xRow;
    private Box box;
    private ArrayList<ArrayList<Integer>> specialRemovedValues;
    private int level = 0;
    
    public Field(int x, int y, Row xRow, Row yRow, Box box, int value) {
        this.possible_values = new ArrayList<Integer>();
        this.specialRemovedValues = new ArrayList<ArrayList<Integer>>();
        this.specialRemovedValues.add(new ArrayList<Integer>());
        this.position_x = x;
        this.position_y = y;
        this.xRow = xRow;
        this.yRow = yRow;
        this.box = box;
        this.value = value;
    }
    
    public boolean generate_possible_values() {
        if(value != 0) {
            return false;
        } else {
            this.possible_values.clear();
            for(int v=1; v<=9; v++){
                Integer suggestion = new Integer(v);
                if(this.getxRow().missing_values.contains(suggestion)
                        && this.getyRow().missing_values.contains(suggestion)
                        && this.box.missing_values.contains(suggestion)) {
                    this.possible_values.add(suggestion);
                }
            }
            for(int i=0; i<specialRemovedValues.size(); i++) {
                if(!this.specialRemovedValues.get(i).isEmpty()) {
                    this.possible_values.removeAll(specialRemovedValues.get(i));
                }
            }
        }
        return true;
    }
    
    public void newSpecialRemovedValues(Integer value) {
        if(!this.specialRemovedValues.get(level).contains(value)) {
            this.specialRemovedValues.get(level).add(value);
        }
        this.possible_values.remove(value);
    }
    
    public void new_level() {
        this.specialRemovedValues.add(new ArrayList<Integer>());
        this.level++;
    }
    
    public void delete_level() {
        this.specialRemovedValues.remove(level);
        this.level--;
    }
    
    public void rollback() {
        this.value = 0;
    }
    
    public void print_possible_values() {
        if(this.possible_values.isEmpty()) {
            System.out.println("isEmpty");
        }
        else {
            StringBuilder sb = new StringBuilder();
            sb.append(this.possible_values.get(0));   
            for(int i=1; i<this.possible_values.size(); i++) {
                sb.append(" ,");
                sb.append(this.possible_values.get(i));
            }
            System.out.println(sb);
        }
    }

    public int getPosition_x() {
        return position_x;
    }

    public int getPosition_y() {
        return position_y;
    }

    public int getValue() {
        return value;
    }

    public ArrayList<Integer> getPossible_values() {
        return possible_values;
    }

    public boolean setValue(int value) {
        
        //System.out.println("Try to set field " + this.position_x + " " + this.position_y + " value to: " + value);
        Integer newValue = new Integer(value);
        if(this.possible_values.remove(newValue)) {
            this.value = value;
            boolean error = false;
            if(!this.xRow.remove_missing_value(newValue)) {
                //System.out.println("Nicht in xRow");
                error = true;
            }
            if(!this.yRow.remove_missing_value(newValue)) {
                //System.out.println("Nicht in yRow");
                error = true;
            }
            if(!this.box.remove_missing_value(newValue)) {
                //System.out.println("Nicht in box");
                error = true;
            }
            
            if(!error) {
                this.possible_values.clear();
                return true;
            }
        }
        //System.out.println("Remove Error bei Feld " + this.position_x + " " + this.position_y + "; Wert: " + value);
        this.value = 0;
        return false;
    }
    
    public void print_field_data() {
        System.out.print("Field: " + this.position_x + " " + this.position_y + "; posVal: ");
        if(this.possible_values.isEmpty()) {
            System.out.println("isEmpty");
        }
        else {
            StringBuilder sb = new StringBuilder();
            sb.append(this.possible_values.get(0));   
            for(int i=1; i<this.possible_values.size(); i++) {
                sb.append(" ,");
                sb.append(this.possible_values.get(i));
            }
            System.out.println(sb);
        }
    }
    
    public int getBoxPosition() {
        return this.box.position;
    }
    
    public Box getBox() {
        return this.box;
    }

    /**
     * @return the yRow
     */
    public Row getyRow() {
        return yRow;
    }

    /**
     * @param yRow the yRow to set
     */
    public void setyRow(Row yRow) {
        this.yRow = yRow;
    }

    /**
     * @return the xRow
     */
    public Row getxRow() {
        return xRow;
    }

    /**
     * @param xRow the xRow to set
     */
    public void setxRow(Row xRow) {
        this.xRow = xRow;
    }
    
}
